package com.jiliang.auth.service.impl;

import com.alibaba.fastjson2.JSON;
import com.jiliang.auth.dao.mapper.*;
import com.jiliang.auth.dao.model.*;
import com.jiliang.auth.domain.AuthFuncBo;
import com.jiliang.auth.domain.AuthRoleFuncBo;
import com.jiliang.auth.service.AuthRoleFuncService;
import com.jiliang.common.bean.BeanCopierDsUtil;
import com.jiliang.common.bean.BeanCopyDsUtil;
import com.jiliang.common.constant.CommonDsConstant;
import com.jiliang.common.string.StringCheckDsUtil;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 角色功能关系
 *
 * @author 
 * @version 1.0
 * @Date 2018/8/14 9:46
 */
@Service
public class AuthRoleFuncServiceImpl implements AuthRoleFuncService {
    private Logger log = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private AuthRoleFuncExMapper authRoleFuncExMapper;
    @Autowired
    private AuthRoleFuncMapper authRoleFuncMapper;
    @Autowired
    private AuthRoleMemberMapper authRoleMemberMapper;
    @Autowired
    private AuthFuncMapper authFuncMapper;
    @Autowired
    private AuthRoleMapper authRoleMapper;

    /**
     * 为角色添加后台和其他平台功能
     *
     * @param roleFuncBo
     * @return void
     * @author 
     * @date 17:45 2019/6/25
     */
    @Override
    public void addHtAndOrderFuncList(AuthRoleFuncBo roleFuncBo) {
        log.info("==========添加内容==========" + roleFuncBo);
        //将历史关系表重置为失效
        log.debug("作废历史角色功能关系");
        AuthRoleFuncExample example = new AuthRoleFuncExample();
        AuthRoleFuncExample.Criteria criteria = example.createCriteria();
        criteria.andRoleCodeEqualTo(roleFuncBo.getRoleCode());
        criteria.andSystemIdEqualTo(roleFuncBo.getSystemId());
        criteria.andSubSystemIdEqualTo(roleFuncBo.getSubSystemId());
        //criteria.andSubSystemIdIn(roleFuncBo.getSubSystemIdList());
        AuthRoleFunc func = new AuthRoleFunc();
        func.setIsEnabled(CommonDsConstant.IS_NOT_ENABLED_VAL);
        authRoleFuncMapper.updateByExampleSelective(func, example);
        if (StringCheckDsUtil.isNotBlank(roleFuncBo.getFuncIds())) {
            String[] funcIdStrs = roleFuncBo.getFuncIds().split(CommonDsConstant.DELIMITER_SG_ZY);
            List<Long> fundIdList = new ArrayList<>();
            for (String funcIdStr : funcIdStrs) {
                Long funcId = Long.valueOf(funcIdStr);
                fundIdList.add(funcId);
            }
            AuthFuncExample funcExp = new AuthFuncExample();
            AuthFuncExample.Criteria funcCrit = funcExp.createCriteria();
            funcCrit.andIdIn(fundIdList);
            funcCrit.andIsEnabledEqualTo(CommonDsConstant.IS_ENABLED_VAL);
            List<AuthFunc> authFuncList = authFuncMapper.selectByExample(funcExp);
            Map<Long, AuthFunc> funcMap = authFuncList.stream().collect(Collectors.toMap(AuthFunc::getId, a->a, (k1, k2)->k1));
            AuthRoleFunc roleFunc = new AuthRoleFunc();
            roleFunc.setRoleCode(roleFuncBo.getRoleCode());
            roleFunc.setSystemId(roleFuncBo.getSystemId());
            AuthFunc tempFunc = null;
            for (Long funcId : fundIdList) {
                tempFunc = funcMap.get(funcId);
                if (tempFunc == null) {
                    continue;
                }
                roleFunc.setFuncId(tempFunc.getId());
                roleFunc.setSubSystemId(tempFunc.getSubSystemId());
                roleFunc.setRoleCode(roleFuncBo.getRoleCode());
                roleFunc.setSystemId(tempFunc.getSystemId());
                int result = authRoleFuncMapper.insertSelective(roleFunc);
                if (result <= 0) {
//                    throw new ServerServiceException(Errors.SYSTEM_INSERT_ERROR);
                }
            }
        }
    }

    /**
     * 查询某个系统下的某个角色的功能（关联功能表）
     *
     * @param roleFuncBo
     * @return java.util.List<com.nxin.middle.jiliang.auth.dao.model.AuthRoleFunc>
     * @author 
     * @date 9:39 2018/8/16
     */
    @Override
    public List<AuthRoleFuncBo> selListByRoleSysId(AuthRoleFuncBo roleFuncBo) {
        log.info("==========查询条件==========" + roleFuncBo);
        if (roleFuncBo == null
                || StringCheckDsUtil.isBlank(roleFuncBo.getRoleCode())
                || roleFuncBo.getSystemId() == null) {
//            throw new ValidationException(Errors.SYSTEM_REQUEST_PARAM_ERROR);
        }
        List<AuthRoleFuncBo> roleFuncBoList = authRoleFuncExMapper.selRoleFuncList(roleFuncBo);
        return roleFuncBoList;
    }

    /**
     * 根据条件查询
     *
     * @param authRoleFunc
     * @return java.util.List<com.nxin.middle.jiliang.auth.dao.model.AuthRoleFunc>
     * @author 
     * @date 17:33 2018/8/14
     */
    @Override
    public List<AuthRoleFunc> selListByParam(AuthRoleFuncBo authRoleFunc) {
        if (authRoleFunc == null) {
            return null;
        }
        log.info("==========查询条件==========" + authRoleFunc);
        AuthRoleFuncExample example = new AuthRoleFuncExample();
        AuthRoleFuncExample.Criteria criteria = example.createCriteria();
        criteria.andIsEnabledEqualTo(CommonDsConstant.IS_ENABLED_VAL);
        if (StringCheckDsUtil.isNotBlank(authRoleFunc.getRoleCode())) {
            criteria.andRoleCodeEqualTo(authRoleFunc.getRoleCode());
        }
        if (authRoleFunc.getSystemId() != null) {
            criteria.andSystemIdEqualTo(authRoleFunc.getSystemId());
        }
        if (authRoleFunc.getSubSystemId() != null) {
            criteria.andSubSystemIdEqualTo(authRoleFunc.getSubSystemId());
        }
        if (authRoleFunc.getFuncId() != null) {
            criteria.andFuncIdEqualTo(authRoleFunc.getFuncId());
        }
        if (StringCheckDsUtil.isNotBlank(authRoleFunc.getRoleCode())) {
            criteria.andRoleCodeEqualTo(authRoleFunc.getRoleCode());
        }
        if (CollectionUtils.isNotEmpty(authRoleFunc.getRoleCodeList())) {
            criteria.andRoleCodeIn(authRoleFunc.getRoleCodeList());
        }

        List<AuthRoleFunc> roleFuncList = authRoleFuncMapper.selectByExample(example);
        return roleFuncList;
    }

    /**
     * 设置角色功能关系
     *
     * @param roleFuncBo
     * @return void
     * @author 
     * @date 13:43 2018/8/14
     */
    @Override
    public void addAuthRoleFunc(AuthRoleFuncBo roleFuncBo) {
        log.info("==========添加内容==========" + roleFuncBo);
        if (roleFuncBo == null
                || StringCheckDsUtil.isBlank(roleFuncBo.getRoleCode())
                || StringCheckDsUtil.isBlank(roleFuncBo.getFuncIds())) {
//            throw new ValidationException(Errors.SYSTEM_REQUEST_PARAM_ERROR);
        }
        if (roleFuncBo.getSystemId() == null) {
            roleFuncBo.setSystemId(CommonDsConstant.SYSTEM_ID_DEFAULT_VAL);
        }
        if (roleFuncBo.getSubSystemId() == null) {
            roleFuncBo.setSubSystemId(CommonDsConstant.SYSTEM_ID_DEFAULT_VAL);
        }
        //将历史关系表重置为失效
        log.debug("作废历史角色功能关系");
        AuthRoleFuncExample example = new AuthRoleFuncExample();
        AuthRoleFuncExample.Criteria criteria = example.createCriteria();
        criteria.andRoleCodeEqualTo(roleFuncBo.getRoleCode());
        criteria.andSystemIdEqualTo(roleFuncBo.getSystemId());
        criteria.andSubSystemIdEqualTo(roleFuncBo.getSubSystemId());
        AuthRoleFunc func = new AuthRoleFunc();
        func.setIsEnabled(CommonDsConstant.IS_NOT_ENABLED_VAL);
        authRoleFuncMapper.updateByExampleSelective(func, example);
        AuthRoleFunc roleFunc = new AuthRoleFunc();
        BeanCopyDsUtil.copyProperties(roleFuncBo, roleFunc);
        String[] funcIds = roleFuncBo.getFuncIds().split(CommonDsConstant.DELIMITER_SG_ZY);
        for (String funcIdStr : funcIds) {
            Long funcId = Long.valueOf(funcIdStr);
            roleFunc.setFuncId(funcId);
            int result = authRoleFuncMapper.insertSelective(roleFunc);
            if (result <= 0) {
//                throw new ServerServiceException(Errors.SYSTEM_INSERT_ERROR);
            }
        }
    }

    @Override
    /**
     * 根据用户BO ID查询权限功能列表
     *
     * @param roleFuncBo 角色功能查询对象，包含用户BO ID、系统ID和子系统ID等查询条件
     * @return 返回与用户角色相关的权限功能列表，如果列表为空或查询结果为空则返回null
     */
    public List<AuthFuncBo> selListByBoId(AuthRoleFuncBo roleFuncBo) {
        // 记录角色功能查询条件的日志信息
        log.info("==========roleFuncBo查询条件==========" + JSON.toJSONString(roleFuncBo));

        // 检查输入参数是否有效，如果为null则抛出异常
        if (roleFuncBo == null || roleFuncBo.getSystemId() == null || roleFuncBo.getSubSystemId() == null) {
//            throw new ValidationException(Errors.SYSTEM_REQUEST_PARAM_ERROR);
        }

        // 根据用户BO ID查询用户角色信息
        AuthRoleMemberExample example = new AuthRoleMemberExample();
        AuthRoleMemberExample.Criteria criteria = example.createCriteria();
        criteria.andBoIdEqualTo(roleFuncBo.getBoId());
        criteria.andSystemIdEqualTo(roleFuncBo.getSystemId());
        criteria.andSubSystemIdEqualTo(roleFuncBo.getSubSystemId());
        criteria.andIsEnabledEqualTo(CommonDsConstant.IS_ENABLED_VAL);

        // 执行查询并获取用户角色列表
        List<AuthRoleMember> authRoleMembers = authRoleMemberMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(authRoleMembers)) {
            // 如果查询结果为空则返回null
            return null;
        }
        // 记录用户角色列表的日志信息
        log.info("==========authRoleMembers返回数据==========" + JSON.toJSONString(authRoleMembers));

        // 准备存储角色编码和ID的列表
        List<String> roleList = new ArrayList<>();
        List<Long> idList = new ArrayList<>();

        // 提取用户角色列表中的角色编码
        for (AuthRoleMember authRoleMember : authRoleMembers) {
            roleList.add(authRoleMember.getRoleCode());
        }

        // 根据角色编码查询角色权限功能
        AuthRoleFuncExample example1 = new AuthRoleFuncExample();
        AuthRoleFuncExample.Criteria criteria1 = example1.createCriteria();
        criteria1.andRoleCodeIn(roleList);
        criteria1.andSystemIdEqualTo(roleFuncBo.getSystemId());
        criteria1.andSubSystemIdEqualTo(roleFuncBo.getSubSystemId());
        criteria1.andIsEnabledEqualTo(CommonDsConstant.IS_ENABLED_VAL);
//        example1.setOrderByClause("sort asc"); // 设置排序条件

        // 执行查询并获取角色权限功能列表
        List<AuthRoleFunc> authRoleFuncs = authRoleFuncMapper.selectByExample(example1);
        if (CollectionUtils.isEmpty(authRoleFuncs)) {
            // 如果查询结果为空则返回null
            return null;
        }
        // 记录角色权限功能列表的日志信息
        log.info("==========authRoleFuncs返回数据==========" + JSON.toJSONString(authRoleFuncs));

        // 提取角色权限功能列表中的功能ID
        for (AuthRoleFunc a : authRoleFuncs) {
            idList.add(a.getFuncId());
        }

        // 根据功能ID获取菜单权限列表
        List<AuthFuncBo> menu = getMenu(0L, roleFuncBo.getSystemId(), idList, roleFuncBo.getSubSystemId());
        // 记录菜单权限列表的日志信息
        log.info("==========menu返回数据==========" + JSON.toJSONString(menu));

        // 返回菜单权限列表
        return menu;
    }


    @Override
    public List<AuthFuncBo> selListBySystemId(AuthRoleFuncBo roleFuncBo) {
        log.info("==========系统id查询菜单条件==========" + roleFuncBo);
        //根据用户boid查询用户角色
        AuthRoleExample example = new AuthRoleExample();
        AuthRoleExample.Criteria criteria = example.createCriteria();
        criteria.andSubSystemIdEqualTo(roleFuncBo.getSubSystemId());
        criteria.andIsEnabledEqualTo(CommonDsConstant.IS_ENABLED_VAL);
        List<AuthRole> authRoles = authRoleMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(authRoles)) {
            return null;
        }
        List<String> roleList = new ArrayList<>();
        List<Long> idList = new ArrayList<>();
        for (AuthRole authRole : authRoles) {
            roleList.add(authRole.getRoleCode());
        }
        AuthRoleFuncExample example1 = new AuthRoleFuncExample();
        AuthRoleFuncExample.Criteria criteria1 = example1.createCriteria();
        criteria1.andRoleCodeIn(roleList);
        criteria1.andIsEnabledEqualTo(CommonDsConstant.IS_ENABLED_VAL);
        example.setOrderByClause("rank asc,sort asc");
        List<AuthRoleFunc> authRoleFuncs = authRoleFuncMapper.selectByExample(example1);
        if (CollectionUtils.isEmpty(authRoleFuncs)) {
            return null;
        }
       /* for (AuthRoleFunc a : authRoleFuncs) {
            idList.add(a.getFuncId());
        }*/

        List<AuthFuncBo> menu = getMenu(0L, roleFuncBo.getSystemId(), idList, roleFuncBo.getSubSystemId());

        return menu;
    }

    @Override
    public List<AuthRoleFunc> selRoleFuncListByBoId(AuthRoleFuncBo roleFuncBo) {
        if(roleFuncBo == null || roleFuncBo.getBoId() == null || StringCheckDsUtil.isBlank(roleFuncBo.getFuncCode())){
//            throw new ValidationException(Errors.SYSTEM_REQUEST_PARAM_ERROR);
        }
        // 查询用户所有角色
        //根据用户boid查询用户角色
        AuthRoleMemberExample example = new AuthRoleMemberExample();
        AuthRoleMemberExample.Criteria criteria = example.createCriteria();
        criteria.andBoIdEqualTo(roleFuncBo.getBoId());
        criteria.andIsEnabledEqualTo(CommonDsConstant.IS_ENABLED_VAL);
        List<AuthRoleMember> authRoleMembers = authRoleMemberMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(authRoleMembers)) {
            return null;
        }
        // 查询该功能id
        AuthFuncExample authFuncExample = new AuthFuncExample();
        authFuncExample.createCriteria().andCodeEqualTo(roleFuncBo.getFuncCode());
        List<AuthFunc> authFuncList = authFuncMapper.selectByExample(authFuncExample);
        if (CollectionUtils.isEmpty(authFuncList)) {
            return null;
        }
        Long id = authFuncList.get(0).getId();
        // 查询角色是否有该功能
        AuthRoleFuncBo authRoleFuncBo = new AuthRoleFuncBo();
        List<String> roleCodeList = authRoleMembers.stream().map(AuthRoleMember::getRoleCode).collect(Collectors.toList());
        authRoleFuncBo.setRoleCodeList(roleCodeList);
        authRoleFuncBo.setFuncId(id);
        List<AuthRoleFunc> roleFuncList = selListByParam(authRoleFuncBo);
        return roleFuncList;
    }

    private List<AuthFuncBo> getMenu(long parentFuncId, Short systemId, List<Long> idList, Short subSystemId) {
        AuthFuncExample authFuncExample = new AuthFuncExample();
        AuthFuncExample.Criteria criteria = authFuncExample.createCriteria();
        criteria.andSystemIdEqualTo(systemId);
        if (CollectionUtils.isNotEmpty(idList)) {
            criteria.andIdIn(idList);
        }
        criteria.andSubSystemIdEqualTo(subSystemId);
        criteria.andParentFuncIdEqualTo(parentFuncId);
        criteria.andIsEnabledEqualTo(CommonDsConstant.IS_ENABLED_VAL);
        authFuncExample.setOrderByClause("sort asc");
        List<AuthFunc> authFuncs = authFuncMapper.selectByExample(authFuncExample);
        if (CollectionUtils.isNotEmpty(authFuncs)) {
            List<AuthFuncBo> menuList = new ArrayList<>();
            for (AuthFunc authFunc : authFuncs) {
                String type = authFunc.getType();
                Long id = authFunc.getId();
                AuthFuncBo authFuncBo = BeanCopierDsUtil.copyProperties(authFunc, AuthFuncBo.class);
                if ("MENU".equals(type)) {
                    List<AuthFuncBo> menu2 = getMenu(id, systemId, idList, subSystemId);
                    if (CollectionUtils.isNotEmpty(menu2)) {
                        authFuncBo.setSubFuncList(menu2);
                    }
                }
                menuList.add(authFuncBo);
            }
            //子菜单排序
            List<AuthFuncBo> menuList2 = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(menuList)) {
                for (AuthFuncBo b : menuList) {
                    List<AuthFuncBo> subFuncList = b.getSubFuncList();
                    if (CollectionUtils.isNotEmpty(subFuncList)) {
                        Collections.sort(subFuncList, new Comparator<AuthFuncBo>() {
                            @Override
                            public int compare(AuthFuncBo o1, AuthFuncBo o2) {
                                int diff = o1.getSort() - o2.getSort();
                                if (diff > 0) {
                                    return 1;
                                } else if (diff < 0) {
                                    return -1;
                                }
                                return 0; //相等为0
                            }
                        });
                    }
                    b.setSubFuncList(subFuncList);
                    menuList2.add(b);
                }

            }
            return menuList2;
        }
        return null;
    }

}
